<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
		<script src="./js/vue.min.js"></script>
	</head>
	<body>
		<div id="app">
			<p>数据库名字:</p>
			<input placeholder="输入要打开的数据库名字" v-model="databaseName" />
			<button @click="openMyDataBase(databaseName,version)">打开数据库</button>
			<button @click="readAll" :disabled="!db">遍历数据</button>
			<button @click="useIndex" :disabled="!db">使用索引</button>
			<button @click="clear" :disabled="!db">清空对象仓库</button>

			<p>主键:</p>
			<input placeholder="输入要读取数据的主键" type="number" v-model="primaryKey" />
			<button @click="read" :disabled="!db">读取数据</button>
			<button @click="remove" :disabled="!db">删除数据</button>

			<p>要修改的属性:</p>
			<input v-model="obj.name" />
			<input v-model="obj.age" />
			<input v-model="obj.email" />
			<button :disabled="!db" @click="updateDate">更新数据</button>

			<p>要插入对象的信息（插入位置是最后一行）:</p>
			<input v-model="obj.name" />
			<input v-model="obj.age" />
			<input v-model="obj.email" />
			<button @click="addRecord(obj)" :disabled="!db">插入一条新数据</button>
		</div>

	</body>
	<script>
		var vm = new Vue({
			el: "#app",
			data: {
				version: 1,
				databaseName: "test",
				db: null,
				request: null,
				primaryKey: 1,
				obj: {
					name: "张三",
					age: 22,
					email: "Zsan@foxmail.com"
				}
			},
			methods: {
				openMyDataBase(databaseName, version) {
					var that = this;
					var db;
					this.request = window.indexedDB.open(databaseName, version);
					this.request.onupgradeneeded = function(e) {
						db = e.target.result;
						console.log("onupgrageneeded");
						// 通常新建数据库以后，第一件事是新建对象仓库（即新建表），并设置主键
						var objectStore;
						if (!db.objectStoreNames.contains(databaseName)) { //如果这个 对象仓库/表 不存在，就新建
							objectStore = db.createObjectStore("person", {
								autoIncrement: true //指定主键为一个递增的整数
							});
						}
						/**
						 * 新建当前数据库的索引
						 * 必须在VersionChange监听函数里调用
						 * objectStore.createIndex(indexName, keyPath, objectParameters)
						 * indexName：索引名
						 * keyPath：主键
						 * objectParameters：配置对象（可选）
						 * unique：如果设为 true，将不允许重复的值
						 * multiEntry：如果设为 true，对于有多个值的主键数组，每个值将在索引里面新建一个条目，否则主键数组对应一个条目。
						 * 
						 * */
						objectStore.createIndex("name","name",{unique:false});//可以重复
						objectStore.createIndex("age","age",{unique:false});//可以重复
						objectStore.createIndex("email","email",{unique:true});//不能重复
					}

					this.request.onsuccess = function(e) {
						db = that.request.result;
						that.db = db;
						console.log("success");
					}

					this.request.onerror = function(e) {
						console.log("error");
					}
				},
				addRecord(obj) {
					var that = this;
					var db = that.db;
					var transaction = db.transaction(["person"],
						"readwrite"); //写入数据需要新建一个事务。新建时必须指定表格名称和操作模式（“只读”或“读写”）
					var objectStore = transaction.objectStore(
						"person"); //新建事务以后，通过IDBTransaction.objectStore(name)方法，拿到 IDBObjectStore 对象
					this.obj.age = parseInt(this.obj.age);
					var request = objectStore.add(obj); //再通过表格对象的add()方法，向表格写入一条记录
					request.onsuccess = function(e) {
						console.log("数据写入成功");
					}
					request.onerror = function(e) {
						console.log("数据写入失败:",e.srcElement.error);
					}
				},
				read() {
					var that = this;
					var db = that.db;
					var transaction = db.transaction(["person"]);
					var objectStore = transaction.objectStore("person");
					var request = objectStore.get(parseInt(this.primaryKey)); //objectStore.get()方法用于读取数据，参数是主键的值。
					request.onsuccess = function(e) {
						if (request.result) {
							var obj = {
								name: "",
								age: 0,
								email: ""
							};
							obj.name = request.result.name;
							obj.age = request.result.age;
							obj.email = request.result.email;
							console.log("obj:", obj);
							that.obj = obj;
						} else {
							console.log("未获得数据记录");
						}
					}

					request.onerror = function(e) {
						console.log("事务失败");
					}
				},
				readAll() {
					var that = this;
					var db = that.db;
					var transaction = db.transaction(["person"]);
					var objectStore = transaction.objectStore(
						"person");
					objectStore.openCursor().onsuccess = function(e) {
						var cursor = e.target.result;
						var obj = {
							primaryKey: 1,
							name: "",
							age: 0,
							email: ""
						};
						if (cursor) {
							obj.primaryKey = cursor.key;
							obj.name = cursor.value.name;
							obj.age = cursor.value.age;
							obj.email = cursor.value.email;
							console.log("obj:", obj);
							cursor.continue();
						} else {
							console.log("没有更多数据了");
						}
					}
				},
				updateDate() {
					var that = this;
					var db = this.db;
					var objectStore = db.transaction("person", "readwrite").objectStore("person");
					/**
					 * 更新数据要使用IDBObject.put()方法。
					 * 第一个参数为新数据
					 * 第二个参数为主键，该参数可选，且只在自动递增时才有必要提供，因为那时主键不包含在数据值里面
					 * */
					this.obj.age = parseInt(this.obj.age);
					var request = objectStore.put(this.obj, parseInt(this.primaryKey));
					// var request = db.transaction(['person'], 'readwrite')
					//     .objectStore('person')
					//     .put({ id: 1, name: '李四', age: 35, email: 'lisi@example.com' }); //put()方法自动更新了主键为1的记录。

					request.onsuccess = function(event) {
						console.log('数据更新成功');
					};

					request.onerror = function(event) {
						console.log('数据更新失败');
					}
				},
				remove() {
					var that = this;
					var db = this.db;
					console.log(this.primaryKey);
					var request = db.transaction("person", "readwrite").objectStore("person").delete(parseInt(this
						.primaryKey));

					request.onsuccess = function(event) {
						console.log('数据删除成功');
					};
				},
				useIndex() {
					var db = this.db;
					var objectStore = db.transaction("person","readonly").objectStore("person");
					var index = objectStore.index("name");
					var request = index.get("张三"); //只返回第一个
					// var request = index.getAll("张三");//返回所有的 “张三”
					
					request.onsuccess = function(e){
						var result = e.target.result;
						if(result){
							console.log("result:",result);
							console.log("索引查询成功");
						}else{
							console.log("索引查询失败");
						}
					}
				},
				clear() {
					var db = this.db;
					var request = db.transaction("person", "readwrite").objectStore("person").clear();
					request.onsuccess = function(e) {
						console.log("清空对象仓库成功");
					}
					request.onerror = function(e) {
						console.log("清空仓库失败");
					}
				}
			}
		})
	</script>
</html>
